<?php

/**
 *  Роутер запросов. Парсит запрос, сравнивает его с шаблоном, вытаскивает Action, передает их назад.
 */
class Router {

   private $routes = array();
 
    public function __construct(){
		$this->loadRoutes();
    }
	
	// Получаем конфигурацию путей из файла.
    private function loadRoutes() {
        $fp = fopen(DIR_APPCONFIG . 'routes.cfg', 'r');
        $strc = 0;
        while (!feof($fp)) {
            $str = fgets($fp);

            $strc++;
            if ($str[0] != "#" && trim($str) != "") {
                $parts = explode('|', $str);

                    $regroutes = explode(',', trim($parts[0]));
                    $newroute = trim($parts[1]);
                    foreach ($regroutes as $pattern) {
                        $this->routes[trim(strtolower($pattern))] = trim($newroute);
                    }
            }
        }
        fclose($fp);
    }

    // Перезагрузка путей
    public function reloadroutes() {
        $this->loadroutes();
    }

    public function getAction($query) {
        $current_route = trim(strtolower($query), '/');
        $routes = $this->routes;
        
        $currentrouteparts = explode('/', $current_route);
        $currentroutelenght = count($currentrouteparts); 
        
        $args = $currentrouteparts;

        if(empty($current_route)) return new Action($routes["%root%"], array());
       
        if (isset($routes[$current_route])) {
            
            return new Action($routes[$current_route], $args);
        }
       
        $total = pow(2, $currentroutelenght);
        $original = $currentrouteparts;
        $mask_value = 0;
        for ($i = 0; $i < $total; $i++) {
            $mask = array_reverse(str_split(sprintf('%0' . $currentroutelenght . 'b', $mask_value)));
            foreach ($mask as $key => $value) {
                if ($value == 1) {
                    if (!is_numeric($currentrouteparts[$key])) {
                        $currentrouteparts[$key] = "%text%";
                    } else {
                        $currentrouteparts[$key] = "%num%";
                    }
                }
            }
            $implodedroute = implode("/", $currentrouteparts);
            if (isset($routes[$implodedroute])) {
                return new Action($routes[$implodedroute], $args);
            } else {
                $currentrouteparts = $original;
            }
            $mask_value++;
        }

        return ActionFactory::createError(NOT_FOUND);
    }

    // Функция парсит запросы
//    public function getAction($query) {
//
//        $query = trim(strtolower($query), '/');
//
//        $_GET['rewritequery'] = $query;
//        //глубина сравнения текущего route с шаблонами из routes.cfg
//        //например поиск подходящего шаблона заканчивается тогда, когда нашли $depth одинаковых аргумента 
//        //в шаблоне. Например $route = 'index/smthpage/lol' будет подходить под шаблон 'index/smthpage' по глубине 2
//        //а lol передастся  в контроллер как аргумент, на этом поиск подходящего шаблона закончится
//        $depth = 5;
//        //найденные подходящие значения шаблонов буду сохраняться сюда, по умаолчнию error
//        $current_route = '';
//        //найденые подходящие аргументы
//        $current_args = array();
//        $max_priority = 0;
//
//        $args = array_filter(explode('/', $query));
//       
//        //dump($args);
//        if (count($args) == 0) {
//            $current_route = $this->routes['%root%'];
//        } else {
//            foreach ($this->routes as $pattern => $route) {
//                $dup_args = $args;
//                $needle = array();
//
//                //в $needle засовываем столько аргментов, склоько есть в шаблоне
//                $numofpatterelem = count(explode('/', $pattern));
//
//                for ($i = 0; $i < $numofpatterelem; $i++) {
//                    $needle[] = array_shift($dup_args);
//                }
//                //dump($needle, "needle");
//                //echo trim(implode('/', $needle), '/').' сравниваем с '.$pattern.'<br>';
//                // если склееный $needle == шаблону, 
//                if (trim(implode('/', $needle), '/') == $pattern) {
//
//                    //--query--   = -pattern-
//                    //foo/bar/lol = foo/bar
//                    //cause foo/bar = foo/bar
//                    //echo trim(implode('/', $needle), '/').' найдено совпадение с '.$pattern.'<br>';
//                    //$priority = 2
//                    $priority = count(explode('/', $pattern));
//                    if ($priority > $max_priority) {
//                        $max_priority = $priority;
//                        $current_route = $route;
//                        $current_args = $dup_args;
//                        //echo"текущим рутом выбран ".$route."<br>";
//                        //echo"Аргументы<br>";
//                        //var_dump($current_args);
//                        //echo"<br>";
//                        if ($priority == $depth)
//                            break;
//                    }
//                }
//            }
//        }
//        if (empty($current_route)) {
//            $current_route = 'Error';
//            $current_args = array(404);
//        }
//        return new Action($current_route, $current_args);
//    }

}
?>
